'use strict';

const iconv = require('iconv-lite');
const url = require('url');
const crypto = require('crypto');
const http = require('http');
const msgConfig = require('./config.json').msgConfig;
const logger = require('./logUtility.js').logger('msgUtility');

/**
 * 发送发送信息请求
 * 
 * @param {Object}exp 快递信息
 * @param {Object}cab 快递柜信息
 * @return {Function*}
 */
function* sendSmsGP(exp, cab) {
    let msgId = generateMsgId();
    let url = generateSendSmsUrl(exp, cab, msgId);
    let responseData = yield getResponseP(url);

    logger.info('Send Sms Exp Info:');
    logger.info(exp);
    logger.info('Send Sms Cab Info:');
    logger.info(cab);
    logger.info('Send Sms Url:');
    logger.info(url);
    logger.info('Send Sms Response:');
    logger.info(responseData);

    if (responseData === '100') {
        return { msgId, msgStatus: '发送成功' };
    } else {
        return { msgId, msgStatus: '发送失败' };
    }
}

/**
 * 根据URL获取结果
 * 
 * @param {string}url URL
 * @return {Promise}
 */
function getResponseP(url) {
    return new Promise(function(resolve, reject) {
        let request = http.get(url, function(res) {
            let data = '';
            res.on('data', chunk => data += chunk);
            res.on('end', function() {
                if (res.statusCode === 200) {
                    resolve(data);
                } else {
                    reject(new Error('请求失败'));
                }
            });
        });
        
        request.on('error', () => reject(new Error('请求异常')));
        request.setTimeout(500, () => reject(new Error('请求超时')))
    });
}

/**
 * 生成信息ID
 * 
 * @return {string}
 */
function generateMsgId() {
    var temp = (new Date()).getTime().toString();
    //确保首位不是0，否则第三方会将首位的0除去
    return "9" + temp.substring(temp.length - 9);
}

/**
 * 生成发送Sms的Url
 * 
 * @param {Object}exp 快递信息
 * @param {Object}cab 快递柜信息
 * @param {string}msgId 信息ID
 * @return {string}
 */
function generateSendSmsUrl(exp, cab, msgId) {
    var url = msgConfig.msgUrl;
    var uid = msgConfig.msgUid;
    var psw = msgConfig.msgPsw;
    var cmd = msgConfig.msgCmd;
    var msg = generateSmsInfo(exp, cab);

    url += "cmd=" + cmd
    url += "&uid=" + uid
    url += "&psw=" + encryptMD5(psw)
    url += "&mobiles=" + exp.expReTel
    url += "&msgid=" + msgId
    url += "&msg=" + encodeGBK(msg)

    return url;
}

/**
 * 根据短信模板生成短信信息
 * 
 * @param {Object}exp 快递信息
 * @param {Object}cab 快递柜信息
 * @return {string}
 */
function generateSmsInfo(exp, cab) {
    return msgConfig.msgTemp.replace('{N}', exp.expReName).replace('{D}', exp.expNo).replace('{G}', exp.expCabinetNo).replace('{M}', cab.cabPwd);
}

/**
 * MD5加密
 * 
 * @param {string}value 需要进行MD5加密的原始字符串
 * @return {string}
 */
function encryptMD5(value) {
    return crypto.createHash('md5').update(value).digest('hex').toUpperCase();
}

/**
 * GBK编码
 * 
 * @param {string}value 需要进行GBK编码的原始字符串
 * @return {string}
 */
function encodeGBK(value) {
    if (value == null || typeof (value) == 'undefined' || value == '') {
        return '';
    }

    var a = value.toString().split('');
    for (var i = 0; i < a.length; i++) {
        var ai = a[i];
        if ((ai >= '0' && ai <= '9') || (ai >= 'A' && ai <= 'Z') || (ai >= 'a' && ai <= 'z') || ai === '.' || ai === '-' || ai === '_') continue;
        var b = iconv.encode(ai, 'gbk');
        var e = ['']; // 注意先放个空字符串，最保证前面有一个%
        for (var j = 0; j < b.length; j++)
            e.push(b.toString('hex', j, j + 1).toUpperCase());
        a[i] = e.join('%');
    }
    return a.join('');
}

exports.sendSmsGP = sendSmsGP;